package com.sky.common.task;

import com.sky.business.sys.domain.Container;
import com.sky.business.sys.domain.ContainerConfig;
import com.sky.business.sys.domain.Node;
import com.sky.business.sys.domain.SystemConfig;
import com.sky.business.sys.service.*;
import com.sky.common.docker.ContainerClient;
import com.sky.common.docker.ContainerOperateService;
import com.sky.common.docker.container.ContainerStateInfo;
import com.sky.common.enums.TaskType;
import com.sky.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 节点监控容器管理任务,定时查看节点上的资源监控容器是否存在并正常运行,若有异常则重新创建容器
 *
 */
@Slf4j
@Component
public class NodeMonitorMgrTask {

    @Autowired
    private NodeService nodeService;

    @Autowired
    private ContainerService containerService;

    @Autowired
    private ContainerConfigService containerConfigService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private ContainerOperateService containerOperateService;

    /**
     * 启动监控容器
     *
     * @param systemConfig 系统配置
     * @param node         节点
     */
    public void startNodeMonitor(SystemConfig systemConfig, Node node) {
        List<ContainerConfig> containerConfigList = containerConfigService.findByTaskTypeAndArch(TaskType.MONITOR, node.getArch());
        if (containerConfigList.isEmpty()) {
            log.error("监控任务无法启动,暂无与节点匹配的镜像.节点id:{}, cpu架构:{}", node.getId(), node.getArch());
        } else {
            ContainerConfig containerConfig = containerConfigList.get(0);
            taskService.startMonitorTask(systemConfig, node, containerConfig);
        }
    }

    @Scheduled(cron = "0 1-59/5 * * * ?")
    public void doTask() {
        SystemConfig systemConfig = systemConfigService.getSystemConfig();
        List<Node> nodeList = nodeService.listUndelete();
        for (Node node : nodeList) {
            try {
                List<Container> containerList = containerService.findByNodeAndTaskType(node.getId(), TaskType.MONITOR);
                boolean start = true;
                if (containerList.size() == 1) {
                    Container currContainer = containerList.get(0);
                    ContainerClient containerClient;
                    if(StringUtils.isEmpty(systemConfig.getCertificatePath())) {
                        containerClient = new ContainerClient(node.getIpAddr(), node.getContainerPort());
                    }else{
                        containerClient = new ContainerClient(node.getIpAddr(),node.getContainerPort(),systemConfig.getCertificatePath());
                    }
                    try {
                        ContainerStateInfo containerStateInfo = containerOperateService.inspect(containerClient, currContainer.getDockerId());
                        if (containerStateInfo.isRunning()) {
                            start = false;
                        }
                    } catch (Exception e) {
                        log.error("检查容器状态发生异常,节点ID:{},节点IP:{},容器ID:{}", node.getId(), node.getIpAddr(), currContainer.getDockerId(), e);
                    }
                }
                if (start) {
                    log.info("启动节点监控任务,节点ID:{},节点IP:{}",node.getId(), node.getIpAddr());
                    startNodeMonitor(systemConfig, node);
                }
            } catch (Exception e) {
                log.error("同步容器状态发生异常,节点ID:{}", node.getId(), e);
            }
        }
    }
}
